package cn.ibizlab.util.helper.typehandler;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 基于JsonTypeHandler 处理List<Long>对象
 *
 * @ClassName LongToStringHandler
 * @Description mybatis long转换为String 相互转换工具类
 */
@MappedTypes({List.class})
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class LongToStringHandler extends AbstractJsonTypeHandler<List<Long>> {
    private static final Logger log = LoggerFactory.getLogger(JacksonTypeHandler.class);
    private static ObjectMapper OBJECT_MAPPER;
    private final Class<?> type;

    public LongToStringHandler(Class<?> type) {
        if (log.isTraceEnabled()) {
            log.trace("JacksonTypeHandler(" + type + ")");
        }

        Assert.notNull(type, "Type argument cannot be null", new Object[0]);
        this.type = type;
    }

    protected List<Long> parse(String json) {
        try {
            List list = (List) getObjectMapper().readValue(json, this.type);
            if (list == null)
                return null;
            else {
                return (List<Long>) list.stream().map(l -> Long.parseLong(l.toString())).collect(Collectors.toList());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    protected String toJson(List<Long> obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static ObjectMapper getObjectMapper() {
        if (null == OBJECT_MAPPER) {
            OBJECT_MAPPER = new ObjectMapper();
        }

        return OBJECT_MAPPER;
    }

    public static void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "ObjectMapper should not be null", new Object[0]);
        OBJECT_MAPPER = objectMapper;
    }
}